package com.shrct.businessprocess.purchase.impl;

import com.google.common.base.Objects;
import com.google.common.collect.Iterables;
import com.shrct.businessprocess.budget.RCBudget;
import com.shrct.businessprocess.product.RCProductEntry;
import com.shrct.businessprocess.product.RCProductSpecification;
import com.shrct.businessprocess.purchase.RCBaseProductPurchaseBudget;
import com.shrct.businessprocess.purchase.RCBudgetContract;
import com.shrct.businessprocess.purchase.RCBudgetContractNormalProductItem;
import com.shrct.businessprocess.purchase.RCIdentifiableProductDeliverItem;
import com.shrct.businessprocess.purchase.RCIdentifiableProductInStockEvent;
import com.shrct.businessprocess.purchase.RCProductAndQuantity;
import com.shrct.businessprocess.purchase.RCProductDeliverItem;
import com.shrct.businessprocess.purchase.RCProductInStockEvent;
import com.shrct.businessprocess.purchase.RCPurchaseOrderItem;
import com.shrct.businessprocess.purchase.impl.RCdentifiableBudgetContractProductItemImpl;
import com.shrct.businessprocess.purchase.proxy.RCBudgetContractNormalProductItemProxy;
import edu.fudan.mylang.pf.IGenericQuery;
import edu.fudan.mylang.pf.IObjectFactory;
import java.util.Collection;
import java.util.Set;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import org.eclipse.xtext.xbase.lib.Functions.Function1;
import org.eclipse.xtext.xbase.lib.Functions.Function2;
import org.eclipse.xtext.xbase.lib.IterableExtensions;
import org.eclipse.xtext.xbase.lib.ObjectExtensions;
import org.eclipse.xtext.xbase.lib.Procedures.Procedure1;

@Entity
@DiscriminatorValue("RCBUDGETCONTRACTNORMALPRODUCTITEM_TYPE")
public class RCBudgetContractNormalProductItemImpl extends RCdentifiableBudgetContractProductItemImpl implements RCBudgetContractNormalProductItem {
  public RCBudgetContractNormalProductItemImpl() {
    super();
  }
  
  public RCBudgetContractNormalProductItemImpl(final RCBudgetContract contract) {
    super( contract);
    
  }
  
  public Iterable<RCProductAndQuantity> getDeliverCandidates() {
    Iterable<RCProductAndQuantity> _xblockexpression = null;
    {
      RCBudgetContract _contract = this.getContract();
      RCBudget _budget = _contract.getBudget();
      RCProductSpecification _productSpec = this.getProductSpec();
      Collection<RCProductDeliverItem> _deliveredItems = ((RCBaseProductPurchaseBudget) _budget).getDeliveredItems(_productSpec);
      final Iterable<RCIdentifiableProductDeliverItem> deliveredItems = Iterables.<RCIdentifiableProductDeliverItem>filter(_deliveredItems, RCIdentifiableProductDeliverItem.class);
      final Function1<RCIdentifiableProductDeliverItem,RCProductEntry> _function = new Function1<RCIdentifiableProductDeliverItem,RCProductEntry>() {
          public RCProductEntry apply(final RCIdentifiableProductDeliverItem it) {
            RCProductEntry _product = it.getProduct();
            return _product;
          }
        };
      Iterable<RCProductEntry> _map = IterableExtensions.<RCIdentifiableProductDeliverItem, RCProductEntry>map(deliveredItems, _function);
      final Function1<RCProductEntry,Boolean> _function_1 = new Function1<RCProductEntry,Boolean>() {
          public Boolean apply(final RCProductEntry p) {
            final Function1<RCIdentifiableProductDeliverItem,Boolean> _function = new Function1<RCIdentifiableProductDeliverItem,Boolean>() {
                public Boolean apply(final RCIdentifiableProductDeliverItem it) {
                  RCProductEntry _product = it.getProduct();
                  boolean _equals = Objects.equal(_product, p);
                  return Boolean.valueOf(_equals);
                }
              };
            Iterable<RCIdentifiableProductDeliverItem> _filter = IterableExtensions.<RCIdentifiableProductDeliverItem>filter(deliveredItems, _function);
            final Function1<RCIdentifiableProductDeliverItem,Integer> _function_1 = new Function1<RCIdentifiableProductDeliverItem,Integer>() {
                public Integer apply(final RCIdentifiableProductDeliverItem it) {
                  Integer _quantity = it.getQuantity();
                  return _quantity;
                }
              };
            Iterable<Integer> _map = IterableExtensions.<RCIdentifiableProductDeliverItem, Integer>map(_filter, _function_1);
            final Function2<Integer,Integer,Integer> _function_2 = new Function2<Integer,Integer,Integer>() {
                public Integer apply(final Integer q1, final Integer q2) {
                  int _plus = ((q1).intValue() + (q2).intValue());
                  return Integer.valueOf(_plus);
                }
              };
            Integer _reduce = IterableExtensions.<Integer>reduce(_map, _function_2);
            boolean _notEquals = ((_reduce).intValue() != 0);
            return Boolean.valueOf(_notEquals);
          }
        };
      Iterable<RCProductEntry> _filter = IterableExtensions.<RCProductEntry>filter(_map, _function_1);
      final Set<RCProductEntry> deliveredItemNonZeros = IterableExtensions.<RCProductEntry>toSet(_filter);
      RCBudgetContract _contract_1 = this.getContract();
      RCBudget _budget_1 = _contract_1.getBudget();
      RCProductSpecification _productSpec_1 = this.getProductSpec();
      Collection<? extends RCProductInStockEvent> _inStockEvents = ((RCBaseProductPurchaseBudget) _budget_1).getInStockEvents(_productSpec_1);
      Iterable<RCIdentifiableProductInStockEvent> _filter_1 = Iterables.<RCIdentifiableProductInStockEvent>filter(_inStockEvents, RCIdentifiableProductInStockEvent.class);
      final Function1<RCIdentifiableProductInStockEvent,Boolean> _function_2 = new Function1<RCIdentifiableProductInStockEvent,Boolean>() {
          public Boolean apply(final RCIdentifiableProductInStockEvent it) {
            RCPurchaseOrderItem _orderItem = it.getOrderItem();
            RCProductSpecification _productSpec = _orderItem.getProductSpec();
            RCProductSpecification _productSpec_1 = RCBudgetContractNormalProductItemImpl.this.getProductSpec();
            boolean _equals = Objects.equal(_productSpec, _productSpec_1);
            return Boolean.valueOf(_equals);
          }
        };
      Iterable<RCIdentifiableProductInStockEvent> _filter_2 = IterableExtensions.<RCIdentifiableProductInStockEvent>filter(_filter_1, _function_2);
      final Function1<RCIdentifiableProductInStockEvent,RCProductEntry> _function_3 = new Function1<RCIdentifiableProductInStockEvent,RCProductEntry>() {
          public RCProductEntry apply(final RCIdentifiableProductInStockEvent it) {
            RCProductEntry _product = it.getProduct();
            return _product;
          }
        };
      final Iterable<RCProductEntry> inStockItems = IterableExtensions.<RCIdentifiableProductInStockEvent, RCProductEntry>map(_filter_2, _function_3);
      final Function1<RCProductEntry,Boolean> _function_4 = new Function1<RCProductEntry,Boolean>() {
          public Boolean apply(final RCProductEntry it) {
            boolean _contains = deliveredItemNonZeros.contains(it);
            boolean _not = (!_contains);
            return Boolean.valueOf(_not);
          }
        };
      Iterable<RCProductEntry> _filter_3 = IterableExtensions.<RCProductEntry>filter(inStockItems, _function_4);
      final Function1<RCProductEntry,RCProductAndQuantity> _function_5 = new Function1<RCProductEntry,RCProductAndQuantity>() {
          public RCProductAndQuantity apply(final RCProductEntry product) {
            RCProductAndQuantity _rCProductAndQuantity = new RCProductAndQuantity();
            final Procedure1<RCProductAndQuantity> _function = new Procedure1<RCProductAndQuantity>() {
                public void apply(final RCProductAndQuantity it) {
                  it.setProduct(product);
                  Integer _count = product.getCount();
                  it.setQuantity(_count);
                }
              };
            RCProductAndQuantity _doubleArrow = ObjectExtensions.<RCProductAndQuantity>operator_doubleArrow(_rCProductAndQuantity, _function);
            return _doubleArrow;
          }
        };
      Iterable<RCProductAndQuantity> _map_1 = IterableExtensions.<RCProductEntry, RCProductAndQuantity>map(_filter_3, _function_5);
      _xblockexpression = (_map_1);
    }
    return _xblockexpression;
  }
  
  public Integer getDeliveredQuantity() {
    int _xblockexpression = (int) 0;
    {
      RCBudgetContract _contract = this.getContract();
      RCBudget _budget = _contract.getBudget();
      RCProductSpecification _productSpec = this.getProductSpec();
      Collection<? extends RCProductInStockEvent> _inStockEvents = ((RCBaseProductPurchaseBudget) _budget).getInStockEvents(_productSpec);
      Iterable<RCIdentifiableProductInStockEvent> _filter = Iterables.<RCIdentifiableProductInStockEvent>filter(_inStockEvents, RCIdentifiableProductInStockEvent.class);
      final Function1<RCIdentifiableProductInStockEvent,Boolean> _function = new Function1<RCIdentifiableProductInStockEvent,Boolean>() {
          public Boolean apply(final RCIdentifiableProductInStockEvent it) {
            RCPurchaseOrderItem _orderItem = it.getOrderItem();
            RCProductSpecification _productSpec = _orderItem.getProductSpec();
            RCProductSpecification _productSpec_1 = RCBudgetContractNormalProductItemImpl.this.getProductSpec();
            boolean _equals = Objects.equal(_productSpec, _productSpec_1);
            return Boolean.valueOf(_equals);
          }
        };
      Iterable<RCIdentifiableProductInStockEvent> _filter_1 = IterableExtensions.<RCIdentifiableProductInStockEvent>filter(_filter, _function);
      final Function1<RCIdentifiableProductInStockEvent,Long> _function_1 = new Function1<RCIdentifiableProductInStockEvent,Long>() {
          public Long apply(final RCIdentifiableProductInStockEvent it) {
            Long _xblockexpression = null;
            {
              final RCProductEntry p = it.getProduct();
              IGenericQuery<Long> query=getObjectFactory().createGenericQuery(Long.class,"select count(e) from com.shrct.businessprocess.purchase.impl.RCIdentifiableNormallProductDeliverItemImpl as e   where ((e.product) = (:p)) and  e.active = 1      ").setParameter("p",p);
              Long _uniqueResult = query.uniqueResult();
              _xblockexpression = (_uniqueResult);
            }
            return _xblockexpression;
          }
        };
      Iterable<Long> _map = IterableExtensions.<RCIdentifiableProductInStockEvent, Long>map(_filter_1, _function_1);
      Iterable<Long> _filterNull = IterableExtensions.<Long>filterNull(_map);
      final Function2<Long,Long,Long> _function_2 = new Function2<Long,Long,Long>() {
          public Long apply(final Long l1, final Long l2) {
            long _plus = ((l1).longValue() + (l2).longValue());
            return Long.valueOf(_plus);
          }
        };
      final Long result = IterableExtensions.<Long>reduce(_filterNull, _function_2);
      int _xifexpression = (int) 0;
      boolean _equals = Objects.equal(result, null);
      if (_equals) {
        _xifexpression = 0;
      } else {
        int _intValue = result.intValue();
        _xifexpression = _intValue;
      }
      _xblockexpression = (_xifexpression);
    }
    return Integer.valueOf(_xblockexpression);
  }
  
  public static RCBudgetContractNormalProductItem create(final RCBudgetContract contract, final IObjectFactory objectFactory) {
    com.shrct.businessprocess.purchase.RCBudgetContractNormalProductItem rCBudgetContractNormalProductItem = new com.shrct.businessprocess.purchase.impl.RCBudgetContractNormalProductItemImpl(
    	contract
    );
    objectFactory.create(rCBudgetContractNormalProductItem);
    return rCBudgetContractNormalProductItem;			
    
  }
  
  public static RCBudgetContractNormalProductItem createRCBudgetContractNormalProductItemImpl(final RCBudgetContract contract, final IObjectFactory objectFactory, final Procedure1<RCBudgetContractNormalProductItem> init) {
    com.shrct.businessprocess.purchase.RCBudgetContractNormalProductItem rCBudgetContractNormalProductItem = new com.shrct.businessprocess.purchase.impl.RCBudgetContractNormalProductItemImpl(
    	contract
    );
    objectFactory.create(rCBudgetContractNormalProductItem);
    init.apply(rCBudgetContractNormalProductItem);
    
    return rCBudgetContractNormalProductItem;			
    
  }
  
  public RCBudgetContractNormalProductItemProxy toProxy() {
    com.shrct.businessprocess.purchase.proxy.RCBudgetContractNormalProductItemProxy proxy = new com.shrct.businessprocess.purchase.proxy.RCBudgetContractNormalProductItemProxy();
    proxy.setId(this.getId());
    if(this instanceof edu.fudan.mylang.pf.INamedModelObject){
    	proxy.setName(((edu.fudan.mylang.pf.INamedModelObject)this).getEntityName());
    }
    return proxy;
    
  }
}
